/** ***********************************************************************************
* @file         flash_buffer.c
* @brief        FLASH底层驱动接口
* @details      主要用来进行对FLASH底层驱动接口进行读、写、擦除等操作
* @author       杨小珛
* @date         2020/03/03
* @copyright    北京高知科技有限公司    
* @version      V1.0
* @attention    无
**************************************************************************************/
#include "flash_buffer.h"
#include "flash_dev.h"
#include "flash_config.h"
#include "flash_config.h"
#include "rtc_task.h"
#include "com_lib.h"

uint32_t flash_spi_dev_flag = 0;

/** ****************************************************************************
* @remarks       uint32_t sfb_bbt_tables_init(void)
* @brief         外部FLASH bbt数据列表初始化
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
uint32_t sfb_bbt_tables_init(void)
{
    flash_spi_dev_flag = flash_spi_dev_init();
    return flash_spi_dev_flag;                  /*系统外部FLASH初始化*/
}


/** ****************************************************************************
* @remarks       uint32_t sfb_handle_init( sfb_buf_rt_t *sfb_handle ,const sfb_setting_t *sfb_set )
* @brief         SFB 数据存储空间，句柄数据初始化
* @param[in]     *sfb_handle SFB句柄数据地址
* @param[in]     *sfb_set SFB设置的参数
* @param[out]    无
* @return        返回 存储的数据的句柄当前位置
* @attention     无
*******************************************************************************/
uint32_t sfb_handle_init( sfb_buf_rt_t *sfb_handle ,const sfb_setting_t *sfb_set )
{
    uint32_t num = 0, handle_num = 0 ;
    uint8_t sfb_handle_data[sizeof(sfb_buf_handle_t)] = { 0 };
    sfb_buf_handle_t *sfb_handle_p = NULL;
	if( ( sfb_handle == NULL ) || ( sfb_set == NULL ))
    {   
		return 0;
    }
    if( flash_spi_dev_flag == pdPASS )
    {
        sfb_handle->sfb_st = SFB_SPACE_STATE_OK;
    }
    else
    {
        sfb_handle->sfb_st = SFB_SPACE_STATE_ERR;
    }
    sfb_handle->sfb_set.handle_add = sfb_set->handle_add;
    
    sfb_handle->sfb_set.base_add = sfb_set->base_add;
    sfb_handle->sfb_set.sec_sz = sfb_set->sec_sz;
    sfb_handle->sfb_set.sectors = sfb_set->sectors;
    sfb_handle->sfb_set.unit_sz = sfb_set->unit_sz;
    sfb_handle->sfb_set.sec_units = sfb_set->sec_units;
    
    sfb_handle->sfb_addr.curwraddr = sfb_handle->sfb_set.base_add;
    sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
    
    sfb_handle->sfb_buf_cache.write = 0;
    sfb_handle->sfb_buf_cache.read = 0;
    
    /*开始查找HANDLE 的节点，查找FALSH 目前的存储节点。*/
    handle_num = SPI_FLASH_MIN_SECTOR / sizeof(sfb_buf_handle_t);
    for( num = 0 ; num < handle_num; num ++ )
    {   
        if( pdPASS ==  sfb_read_buf( sfb_handle->sfb_set.handle_add + ( num * sizeof(sfb_buf_handle_t) ), (uint8_t* )sfb_handle_data, sizeof(sfb_buf_handle_t)) )
        {
            sfb_handle_p = (sfb_buf_handle_t *)sfb_handle_data;
            if( sfb_handle_p->crc32 == calculate_crc32( CRC_INIT, (uint8_t *)sfb_handle_data , sizeof(sfb_buf_handle_t) - sizeof(uint32_t) ) )
            {
                sfb_handle->sfb_addr.curwraddr = sfb_handle_p->addr.curwraddr;
                sfb_handle->sfb_addr.currdaddr = sfb_handle_p->addr.currdaddr;
                
                sfb_handle->sfb_buf_cache.write = sfb_handle_p->cache.write;
                sfb_handle->sfb_buf_cache.read = sfb_handle_p->cache.read;
                /*写地址不满足条件*/
                if(( sfb_handle->sfb_addr.curwraddr < sfb_handle->sfb_set.base_add ) || ( sfb_handle->sfb_addr.curwraddr >= SPIBUF_END_ADDR_GET( sfb_handle ) ) )
                {
                    sfb_handle->sfb_addr.curwraddr = sfb_handle->sfb_set.base_add;
                    sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
                    
                    sfb_handle->sfb_buf_cache.write = 0;
                    sfb_handle->sfb_buf_cache.read = 0;
                    num = 0;
                    break;
                }
                /*读地址不满足条件*/
                if(( sfb_handle->sfb_addr.currdaddr < sfb_handle->sfb_set.base_add ) || ( sfb_handle->sfb_addr.curwraddr >= SPIBUF_END_ADDR_GET( sfb_handle ) ) )
                {
                    sfb_handle->sfb_addr.curwraddr = sfb_handle->sfb_set.base_add;
                    sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
                    
                    sfb_handle->sfb_buf_cache.write = 0;
                    sfb_handle->sfb_buf_cache.read = 0;
                    num = 0;
                    break;
                }
                
            }
            else/*数据校验失败后，则牵制把内存参数设置为初始状态*/
            {   
                if(( sfb_handle_p->addr.curwraddr != 0xFFFFFFFF ) || ( sfb_handle_p->addr.currdaddr != 0xFFFFFFFF ))
                {
                    sfb_handle->sfb_addr.curwraddr = sfb_handle->sfb_set.base_add;
                    sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
                    
                    sfb_handle->sfb_buf_cache.write = 0;
                    sfb_handle->sfb_buf_cache.read = 0;
                    num = 0;
                }
                break;
            }
        }
        else
        {
            sfb_handle->sfb_addr.curwraddr = sfb_handle->sfb_set.base_add;
            sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
            
            sfb_handle->sfb_buf_cache.write = 0;
            sfb_handle->sfb_buf_cache.read = 0;
            num = 0;
            break;
        }
    }
    return num;
}

/** ****************************************************************************
* @remarks       uint32_t  sfb_block_reset( uint32_t addr, uint32_t sectors )
* @brief         SFB 数据空间复位操作
* @param[in]     addr 开始地址
* @param[in]     sectors 选择的块数量
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
void  sfb_block_reset( uint32_t addr, uint32_t sectors )
{
    while( sectors-- )
    {
        if( flash_spi_sector_erase( addr ) == pdPASS )
        {
            addr += SPI_FLASH_MIN_SECTOR;
            gaoz_task_sleep( 10 );
        }
        else
        {
            break;
        }
    }
}

/** ****************************************************************************
* @remarks       void sfb_address_check( sfb_buf_rt_t *sfb_handle )
* @brief         检测SFB 地址的合法性
* @param[in]     *sfb_handle 读写数据的句柄
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
void sfb_address_check( sfb_buf_rt_t *sfb_handle )
{
	uint32_t wblock = 0 , rblock = 0;
	if( sfb_handle == NULL )
	{
		return;
	}
	/*正常情况下写地址应大于读地址或等于读地址，当写地址小于读地址时处于循环写状态*/
	if( sfb_handle->sfb_buf_cache.write >= sfb_handle->sfb_buf_cache.read )
	{
		return; /*正常情况*/
	}
	else
	{ 
		wblock = sfb_handle->sfb_buf_cache.write / sfb_handle->sfb_set.sec_units;
		rblock = sfb_handle->sfb_buf_cache.read / sfb_handle->sfb_set.sec_units;
		if( wblock == rblock ) /*当写数据指针与读数据指针在相同的存储块内时，将读数据向前移动一块，保证读/写数据不重合*/
		{
			rblock = rblock + 1;
			sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add + sfb_handle->sfb_set.sec_sz * rblock;
			sfb_handle->sfb_buf_cache.read = rblock * sfb_handle->sfb_set.sec_units;
			if( sfb_handle->sfb_addr.currdaddr >= SPIBUF_END_ADDR_GET( sfb_handle ) )
			{	
				sfb_handle->sfb_buf_cache.read = 0;
				sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
			}
		}
	}
}

/** ****************************************************************************
* @remarks       uint32_t sfb_unit_write( sfb_buf_rt_t *sfb_handle , uint8_t* data , sfb_index_t *windex)
* @brief         数据写入到外部FLASH 中
* @param[in]     *sfb_handle 读写数据的句柄
* @param[in]     *data 写入的数据地址
* @param[in]     *windex 写入数据的状态
* @param[out]    无
* @return        pdPASS 写入数据成功 ，pdFAIL 写入数据失败
* @attention     无
*******************************************************************************/
uint32_t sfb_unit_write( sfb_buf_rt_t *sfb_handle , uint8_t *data , sfb_index_t *windex)
{
    uint32_t addr = 0;
	uint32_t block = 0;
    sfb_index_t xindex;
    if(( sfb_handle == NULL ) || ( data == NULL ) || ( windex == NULL ))
    {
        return pdFAIL;
    }
    if( windex->usdatalen == 0 ) 
    {
        return pdFAIL;
    }
    if(( sfb_handle->sfb_addr.curwraddr < sfb_handle->sfb_set.base_add ) || ( sfb_handle->sfb_addr.curwraddr >= SPIBUF_END_ADDR_GET( sfb_handle ) ) )
    {
        addr = sfb_handle->sfb_set.base_add;
        sfb_handle->sfb_addr.curwraddr = addr;
    }
    else
    {
    	addr = sfb_handle->sfb_addr.curwraddr;
    }
	/*检测读取FLASH数据地址的合法性*/
	sfb_address_check( sfb_handle );
    /*读取数据存储的索引状态*/
    if( flash_spi_read_data( addr, ( uint8_t* )&xindex, sizeof( sfb_index_t ) ) == pdFAIL )
    {
        return pdFAIL;
    }
	/*计算是否为块的整数倍*/
	block = addr % SPI_FLASH_MIN_SECTOR; /*防止初始状态时没有被擦除*/
	/*比较前4个字节的FLASH状态 如果不为擦除状态则重新擦除*/
    if(( *(( uint32_t* )&xindex ) != 0xFFFFFFFF ) || ( block == 0 ))
    {	/*已经产生循环数据*/
        sfb_block_reset( addr,1 );
        memset( &xindex, 0xFF, sizeof( sfb_index_t ) );
    }
    /*将需要写入的数据保存到FLASH中，并添加头不信息*/
    xindex = *windex;
    if( flash_spi_write_data( addr + sizeof( sfb_index_t ) , data , windex->usdatalen ) == pdFAIL )
    {
        return pdFAIL;
    }
    xindex.bwrite = 0;
    xindex.bwrdone = 0;
    if( flash_spi_write_data( addr, ( uint8_t * )&xindex, sizeof( sfb_index_t ) ) == pdFAIL )
    {
        return pdFAIL;
    }
    sfb_handle->sfb_addr.curwraddr += sfb_handle->sfb_set.unit_sz;
    sfb_handle->sfb_buf_cache.write ++;
    if( sfb_handle->sfb_addr.curwraddr >= SPIBUF_END_ADDR_GET( sfb_handle ) )
    {
    	sfb_handle->sfb_buf_cache.write = 0;
        sfb_handle->sfb_addr.curwraddr  = sfb_handle->sfb_set.base_add;
    }

    return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_unit_read( sfb_buf_rt_t *sfb_handle , sfb_direction_e direct, uint32_t unit, uint32_t size, uint8_t* data ,sfb_index_t* rindex)
* @brief         读取FLASH 数据
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[in]     direct 读取数据的方向 (SFB_SEARCH_CYCLE 默认为循环读取) 
* @param[in]     unit 读取的最小单元数 (默认为1 )
* @param[in]     size 读取的最长数据
* @param[in]     sf_index_s* rindex 读取数据的状态
* @param[out]    无
* @return        pdPASS 读取数据成功 ，pdFAIL 读取数据失败
* @attention     无
*******************************************************************************/
uint32_t sfb_unit_read( sfb_buf_rt_t *sfb_handle , sfb_direction_e direct, uint32_t unit, uint32_t size, uint8_t* data ,sfb_index_t* rindex)
{
	uint32_t addr = 0 , ret = pdFAIL;
	sfb_index_t xindex;
	memset(( void* )&xindex, 0xFF, sizeof( sfb_index_t ) );
	if(( sfb_handle == NULL ) || ( data == NULL ) || ( rindex == NULL ))
	{
		return ret;
	}
	if(( unit == 0 ) || ( size == 0))
	{
		return ret;
	}
	if(( sfb_handle->sfb_addr.currdaddr < sfb_handle->sfb_set.base_add ) || ( sfb_handle->sfb_addr.curwraddr >= SPIBUF_END_ADDR_GET( sfb_handle ) ) )
	{
		addr = sfb_handle->sfb_set.base_add;
		sfb_handle->sfb_addr.currdaddr = addr;
	}
	else
	{
		addr = sfb_handle->sfb_addr.currdaddr;
	}
	/*读取数据存储的索引状态*/
	if( flash_spi_read_data( addr, ( uint8_t* )&xindex, sizeof( sfb_index_t )) == pdFAIL )
    {
        return pdFAIL;
    }   
	/*判FLASH空间数据的正确性*/
    if( *(( uint32_t* )&xindex ) == 0xFFFFFFFF )
    {
		/*当数据没有被写入或者已经发送成功或者已经被删除，那么就会对地址自动的加一个单元地址 */
		sfb_handle->sfb_addr.currdaddr += sfb_handle->sfb_set.unit_sz;
		sfb_handle->sfb_buf_cache.read ++;
		if( sfb_handle->sfb_addr.currdaddr >= SPIBUF_END_ADDR_GET( sfb_handle ) )
		{
			sfb_handle->sfb_buf_cache.read = 0;
			sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
		}
		return pdFAIL;
	}
	/* 读取存储的数据状态 数据已经被写入而且没有被发送成功，也没有被删除 */
	if( xindex.bwrdone == 0 )
	{
		if(( xindex.bsenddone != 0 ) && ( xindex.bdel != 0 ) )
		{
			if( xindex.usdatalen > size )
			{
				xindex.usdatalen = size;
			}
			if( flash_spi_read_data( addr + sizeof( sfb_index_t ) , data, xindex.usdatalen ) == pdFAIL )
            {
                return pdFAIL;
            }         
			if( xindex.usdatalen != 0 )
			{
				xindex.bread = 0;
				xindex.bredone = 0;
				if( flash_spi_write_data( addr, ( uint8_t * )&xindex, sizeof( sfb_index_t ) )  == pdFAIL )
                {
                    return pdFAIL;
                }            
			}
			#if 1
			if( flash_spi_read_data( addr, ( uint8_t* )&xindex, sizeof( sfb_index_t ) )  == pdFAIL )
            {
                return pdFAIL;
            }         
			if((xindex.bredone != 0) || (xindex.bread != 0))
			{
				xindex.bredone = 0;
				xindex.bread = 0;
				if( flash_spi_write_data( addr, ( uint8_t * )&xindex, sizeof( sfb_index_t ) )  == pdFAIL )
                {
                    return pdFAIL;
                }            
			}
			#endif
			ret = pdPASS;
			*rindex = xindex;
		}
		else
		{
			/*当数据没有被写入或者已经发送成功或者已经被删除，那么就会对地址自动的加一个单元地址 */
			sfb_handle->sfb_addr.currdaddr += sfb_handle->sfb_set.unit_sz;
			sfb_handle->sfb_buf_cache.read ++;
			if( sfb_handle->sfb_addr.currdaddr >= SPIBUF_END_ADDR_GET( sfb_handle ) )
			{
				sfb_handle->sfb_buf_cache.read = 0;
				sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
			}
			ret = pdFAIL;
		}
	}
	return ret;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_directly_read( sfb_buf_rt_t *sfb_handle , sfb_direction_e direct ,uint32_t unit, uint32_t size,uint8_t* data ,sfb_index_t *rindex)
* @brief         读取FLASH 数据
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[in]     direct 读取数据的方向 (SFB_SEARCH_CYCLE 默认为循环读取) 
* @param[in]     unit 读取的最小单元数 (默认为1 )
* @param[in]     size 读取的最长数据
* @param[in]     sf_index_s* rindex 读取数据的状态
* @param[out]    无
* @return        pdPASS 读取数据成功 ，pdFAIL 读取数据失败
* @attention     无
*******************************************************************************/
uint32_t sfb_directly_read( sfb_buf_rt_t *sfb_handle , sfb_direction_e direct ,uint32_t unit, uint32_t size,uint8_t* data ,sfb_index_t *rindex)
{
	uint32_t addr = 0 , ret = pdFAIL;
	sfb_index_t xindex;
    
	memset(( void* )&xindex, 0xFF, sizeof( sfb_index_t ) );
	if(( sfb_handle == NULL ) || ( data == NULL ) || ( rindex == NULL ))
	{
		return ret;
	}
	if(( unit == 0 ) || ( size == 0))
	{
		return ret;
	}
	if(( sfb_handle->sfb_addr.currdaddr < sfb_handle->sfb_set.base_add ) || ( sfb_handle->sfb_addr.curwraddr >= SPIBUF_END_ADDR_GET( sfb_handle ) ) )
	{
		addr = sfb_handle->sfb_set.base_add;
		sfb_handle->sfb_addr.currdaddr = addr;
	}
	else
	{
		addr = sfb_handle->sfb_addr.currdaddr;
	}
	/*读取数据存储的索引状态*/
	if( flash_spi_read_data( addr, ( uint8_t* )&xindex, sizeof( sfb_index_t )) == pdFAIL )
    {
        return pdFAIL;
    }   
	/*判FLASH空间数据的正确性*/
    if( *(( uint32_t* )&xindex ) == 0xFFFFFFFF )
    {
		return pdFAIL;
	}
	/* 读取存储的数据状态 数据已经被写入则直接读取*/
	if( xindex.bwrdone == 0 )
	{
		if( xindex.usdatalen > size )
		{
			xindex.usdatalen = size;
		}
		if( flash_spi_read_data( addr + sizeof( sfb_index_t ) , data, xindex.usdatalen ) == pdFAIL )
        {
            return pdFAIL;
        }      
		ret = pdPASS;
		*rindex = xindex;
	}
    
	return ret;
}

/** ****************************************************************************
* @remarks       void sfb_read_reset( sfb_buf_rt_t *sfb_handle)
* @brief         复位方向读数据地址，将读取数据的地址和条数设置为和写数据相同
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
void sfb_read_reset( sfb_buf_rt_t *sfb_handle)
{
	if( sfb_handle == NULL )
    {   
		return;
    }
	sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_addr.curwraddr;
	sfb_handle->sfb_buf_cache.read = sfb_handle->sfb_buf_cache.write;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_send_succ( sfb_buf_rt_t *sfb_handle )
* @brief         数据发送成功 写发送成功标识
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[out]    无
* @return        pdPASS 成功 ，pdFAIL 失败
* @attention     无
*******************************************************************************/
uint32_t sfb_send_succ( sfb_buf_rt_t *sfb_handle )
{
	uint32_t addr = 0 , ret = pdFAIL ;
	sfb_index_t xindex;
	if( sfb_handle == NULL )
		return ret;
	if(( sfb_handle->sfb_addr.currdaddr < sfb_handle->sfb_set.base_add ) || ( sfb_handle->sfb_addr.curwraddr >= SPIBUF_END_ADDR_GET( sfb_handle ) ) )
	{
		addr = sfb_handle->sfb_set.base_add;
		sfb_handle->sfb_addr.currdaddr = addr;
	}
	else
	{
		addr = sfb_handle->sfb_addr.currdaddr;
	}
	/*读取数据存储的索引状态*/
	if( flash_spi_read_data( addr, ( uint8_t* )&xindex, sizeof( sfb_index_t ) ) == pdFAIL )
    {
        return pdFAIL;
    }   
	if(( xindex.bredone ==0 ) && ( xindex.bsenddone != 0))
	{
		xindex.bsenddone = 0;
		if( flash_spi_read_data( addr, ( uint8_t * )&xindex, sizeof( sfb_index_t ) ) == pdFAIL )
        {
            return pdFAIL;
        }      
		sfb_handle->sfb_addr.currdaddr += sfb_handle->sfb_set.unit_sz;
		sfb_handle->sfb_buf_cache.read ++;
		if( sfb_handle->sfb_addr.currdaddr >= SPIBUF_END_ADDR_GET( sfb_handle ) )
		{
			sfb_handle->sfb_buf_cache.read = 0;
			sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
		}
		ret = pdPASS;
	}
	return ret;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_delete_all( sfb_buf_rt_t *sfb_handle )
* @brief         删除所有数据
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[out]    无
* @return        pdPASS 成功 ，pdFAIL 失败
* @attention     无
*******************************************************************************/
uint32_t sfb_delete_all( sfb_buf_rt_t *sfb_handle )
{
	uint32_t addr = 0 , num = 0 ,i = 0;
	sfb_index_t xindex;
	if( sfb_handle == NULL )
    {   
		return pdFAIL;
    }
	addr = sfb_handle->sfb_set.base_add;
	memset( &xindex, 0xFF, sizeof( sfb_index_t ) );
	num = sfb_handle->sfb_set.sectors * sfb_handle->sfb_set.sec_units;
	
	for( i = 0 ; i < num ; i ++ )
	{	
		/*读取数据存储的索引状态*/
		if( flash_spi_read_data( addr, ( uint8_t* )&xindex, sizeof( sfb_index_t ) ) == pdFAIL )
        {
            return pdFAIL;
        }      
		if( *(( uint32_t* )&xindex ) != 0xFFFFFFFF ) 
		{	/*已经产生循环数据*/
			if( xindex.bdel != 0 ) 
			{
				xindex.bdel = 0;
				if( flash_spi_read_data( addr, ( uint8_t * )&xindex, sizeof( sfb_index_t ) ) == pdFAIL )
                {
                    return pdFAIL;
                }
			}
			memset( &xindex, 0xFF, sizeof( sfb_index_t ) );
		}
		addr += sfb_handle->sfb_set.unit_sz;
	}
	/*将其他参数进行初始化*/
	sfb_handle->sfb_addr.curwraddr = sfb_handle->sfb_set.base_add;
	sfb_handle->sfb_addr.currdaddr = sfb_handle->sfb_set.base_add;
	sfb_handle->sfb_buf_cache.write = 0;
	sfb_handle->sfb_buf_cache.read = 0;
	return pdPASS;
}	

/** ****************************************************************************
* @remarks       uint32_t sfb_read_index( uint32_t addr, sfb_index_t* xindex)
* @brief         读取存储单元内的存储信息
* @param[in]     addr 读取数据的地址
* @param[out]    *xindex 返回的数据条目的地址数据
* @return        pdPASS 成功 ，pdFAIL 失败
* @attention     无
*******************************************************************************/
uint32_t sfb_read_index( uint32_t addr, sfb_index_t *xindex )
{
	if( xindex == NULL )
	{
		return pdFAIL;
	}
	if( flash_spi_read_data( addr, ( uint8_t* )xindex, sizeof( sfb_index_t ) ) == pdFAIL )
    {
        return pdFAIL;
    }   
	return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_units_cn_get( sfb_buf_rt_t *sfb_handle, uint32_t *unit_num )
* @brief         获取数据的单元数据
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[out]    *unit_num 返回的数据条目的地址数据
* @return        pdPASS 成功 ，pdFAIL 失败
* @attention     无
*******************************************************************************/
uint32_t sfb_units_cn_get( sfb_buf_rt_t *sfb_handle, uint32_t *unit_num )
{	
	if(( sfb_handle == NULL ) || ( unit_num == NULL ))
	{
		return pdFAIL;
	}
	if( sfb_handle->sfb_buf_cache.write >= sfb_handle->sfb_buf_cache.read )
	{
		*unit_num = sfb_handle->sfb_buf_cache.write - sfb_handle->sfb_buf_cache.read;
	}
	else
	{
		*unit_num =(( sfb_handle->sfb_set.sectors * sfb_handle->sfb_set.sec_units ) - sfb_handle->sfb_buf_cache.read ) + sfb_handle->sfb_buf_cache.write;
	}
	return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_write_position_get( sfb_buf_rt_t *sfb_handle, uint32_t *position )
* @brief         获取当前写的位置
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[out]    *position 当前写的位置
* @return        pdPASS 成功 ，pdFAIL 失败
* @attention     无
*******************************************************************************/
uint32_t sfb_write_position_get( sfb_buf_rt_t *sfb_handle, uint32_t *position )
{	
	if(( sfb_handle == NULL ) || ( position == NULL ))
	{
		return pdFAIL;
	}
	*position = sfb_handle->sfb_buf_cache.write;
	return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_read_position_get( sfb_buf_rt_t *sfb_handle, uint32_t *position )
* @brief         获取当前读的位置
* @param[in]     * sfb_handle 读取flash 数据的句柄
* @param[out]    *position 当前读的位置
* @return        pdPASS 成功 ，pdFAIL 失败
* @attention     无
*******************************************************************************/
uint32_t sfb_read_position_get( sfb_buf_rt_t *sfb_handle, uint32_t *position )
{	
	if(( sfb_handle == NULL ) || ( position == NULL ))
	{
		return pdFAIL;
	}
	*position = sfb_handle->sfb_buf_cache.read;
	return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_read_buf(uint32_t addr, uint8_t* buf, uint16_t len)
* @brief         读取FLASH 数据
* @param[in]     addr flash地址
* @param[in]     size 读取数据的长度
* @param[out]    *pbuff 读取数据地址
* @return        无
* @attention     无
*******************************************************************************/
uint32_t sfb_read_buf(uint32_t addr, uint8_t* buf, uint16_t len)
{
	return flash_spi_read_data( addr, ( uint8_t* )buf, len );
}

/** ****************************************************************************
* @remarks       uint32_t sfb_write_buf(uint32_t addr, uint8_t* buf, uint16_t len)
* @brief         写FLASH 空间数据 
* @param[in]     addr 写空间地址
* @param[in]     *pbuff 写数据地址
* @param[in]     size 写数据长度
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
uint32_t sfb_write_buf(uint32_t addr, uint8_t* buf, uint16_t len)
{
	return flash_spi_write_data( addr, ( uint8_t* )buf, len );
}

/** ****************************************************************************
* @remarks       uint32_t sfb_write_handle_position( sfb_buf_rt_t *sfb_handle, uint32_t *position )
* @brief         写SFB HANDLE 当前的位置 
* @param[in]     addr 写空间地址
* @param[out]    *position 当前的位置
* @return        pdPASS 成功 ，pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t sfb_write_handle_position( sfb_buf_rt_t *sfb_handle, uint32_t *position )
{
    uint32_t handle_num = 0 , i = 0 , ret = pdFAIL;
    sfb_buf_handle_t sfb_handle_data = { 0 };
    uint8_t sfb_handle_read[sizeof(sfb_buf_handle_t)] = { 0 };
    sfb_buf_handle_t *sfb_handle_p = NULL;
    
	if(( sfb_handle == NULL ) || ( position == NULL ))
	{
		return pdFAIL;
	}
    /*判断当前HANDLE 的位置为0时重新擦除块数据*/
    if( *position == 0 )
    {
        if( flash_spi_sector_erase( sfb_handle->sfb_set.handle_add ) == pdFAIL )
        {
            return pdFAIL;
        }
    }
    /*前装当前最新的数据*/
    sfb_handle_data.addr.curwraddr = sfb_handle->sfb_addr.curwraddr;
    sfb_handle_data.addr.currdaddr = sfb_handle->sfb_addr.currdaddr;
    sfb_handle_data.cache.write = sfb_handle->sfb_buf_cache.write;
    sfb_handle_data.cache.read = sfb_handle->sfb_buf_cache.read;
    sfb_handle_data.crc32 = calculate_crc32( CRC_INIT, (uint8_t *)&sfb_handle_data , sizeof(sfb_buf_handle_t) - sizeof(uint32_t) );
    /*将数据写入到FLASH 中，再读出来进行CRC数据校验，保证数据的正确性。如果没有*/
    for( i = 0 ; i < 3 ; i ++ )
    {
        if( pdPASS == sfb_write_buf( sfb_handle->sfb_set.handle_add + ( *position * sizeof(sfb_buf_handle_t) ), (uint8_t*)&sfb_handle_data, sizeof(sfb_buf_handle_t) ) )
        {
            if( pdPASS ==  sfb_read_buf( sfb_handle->sfb_set.handle_add + ( *position * sizeof(sfb_buf_handle_t) ), (uint8_t* )sfb_handle_read, sizeof(sfb_buf_handle_t)) )
            {
                sfb_handle_p = (sfb_buf_handle_t *)sfb_handle_read;
                if( sfb_handle_p->crc32 == calculate_crc32( CRC_INIT, (uint8_t *)sfb_handle_read , sizeof(sfb_buf_handle_t) - sizeof(uint32_t) ) )
                {
                    ret = pdPASS;
                    break;
                }
            }
        }
    }
    if( ret == pdPASS )
    {
        /*对数据重新复位*/
        handle_num = ( uint32_t )( SPI_FLASH_MIN_SECTOR / sizeof(sfb_buf_handle_t) );
        *position += 1;
        if( *position >= handle_num )
        {
             *position = 0;
        }
    }
    else
    {   /*写数据失败后将FLASH 擦除，再写一次。确保写数据的稳定性。*/
        *position = 0;
        if( flash_spi_sector_erase( sfb_handle->sfb_set.handle_add ) == pdFAIL )
        {
            return pdFAIL;
        }
        if( pdPASS == sfb_write_buf( sfb_handle->sfb_set.handle_add + ( *position * sizeof(sfb_buf_handle_t) ), (uint8_t*)&sfb_handle_data, sizeof(sfb_buf_handle_t) ) )
        {
            if( pdPASS ==  sfb_read_buf( sfb_handle->sfb_set.handle_add + ( *position * sizeof(sfb_buf_handle_t) ), (uint8_t* )sfb_handle_read, sizeof(sfb_buf_handle_t)) )
            {
                sfb_handle_p = (sfb_buf_handle_t *)sfb_handle_read;
                if( sfb_handle_p->crc32 == calculate_crc32( CRC_INIT, (uint8_t *)sfb_handle_read , sizeof(sfb_buf_handle_t) - sizeof(uint32_t) ) )
                {
                    ret = pdPASS;
                }
            }
        }
    }
	return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_write_par_store( uint32_t addr , sfb_buf_store_infor_s *infor )
* @brief         系统参数写入FLASH 内存接口 带CRC32校验
* @param[in]     addr 写入参数地址 
* @param[in]     *infor 写入参数信息
* @param[out]    无
* @return        >0 写入的数据长度  =0 写入的数据过长 或者指针为空
* @attention     无
*******************************************************************************/
uint32_t sfb_write_par_store( uint32_t addr , sfb_buf_store_infor_s *infor )
{
	uint32_t data_len = 0;
	if( infor->infor_p == NULL  )
	{
		return 0;
	}
	if(( infor->infor_len > 1024 ) || ( infor->infor_len == 0 ))
	{
		return 0;
	}
    if( flash_spi_sector_erase( addr ) == pdFAIL )
    {
        return 0;
    }
	if( sfb_write_buf( (addr + data_len), ( uint8_t* )&infor->infor_len, sizeof(uint32_t) ) == pdFAIL )
    {
        return 0;
    }   
	data_len += sizeof(uint32_t);
	if( sfb_write_buf( (addr + data_len), ( uint8_t* )infor->infor_p, infor->infor_len ) == pdFAIL )
    {
        return 0;
    }   
    data_len += infor->infor_len;
	infor->infor_crc = calculate_crc32(CRC_INIT, (uint8_t *)infor->infor_p , infor->infor_len );	
	if( sfb_write_buf( (addr + data_len), ( uint8_t* )&infor->infor_crc, sizeof(uint32_t) ) == pdFAIL )
    {
        return 0;
    }   
    data_len += sizeof(uint32_t);
	return data_len;
}

/** ****************************************************************************
* @remarks       uint32_t sfb_read_par_store( uint32_t addr , sfb_buf_store_infor_s *infor )
* @brief         系统参数读取FLASH 内存接口 带CRC32校验
* @param[in]     addr 读取参数地址 
* @param[out]    *infor 读取参数信息
* @return        >0 返回读取数据的长度   =0 数据CRC错误 或者读取的数据大于1024 或者 等于0
* @attention     无
*******************************************************************************/
uint32_t sfb_read_par_store( uint32_t addr , sfb_buf_store_infor_s *infor )
{
	uint32_t data_len = 0 , data_crc = 0,read_len = 0;
	if( infor->infor_p == NULL )
	{
		return 0;
	}
	if( sfb_read_buf( (addr + data_len), ( uint8_t* )&read_len, sizeof(uint32_t) ) == pdFAIL )
    {
		return 0;
	}    
	if(( read_len > 1024 ) || ( read_len == 0 ))
	{
		return 0;
	}
	if( infor->infor_len != read_len )
	{
		return 0;
	}
	data_len += sizeof(uint32_t);
	if( sfb_read_buf( (addr + data_len), ( uint8_t* )infor->infor_p, infor->infor_len ) == pdFAIL )
    {
		return 0;
	}    
	data_len += infor->infor_len;
	if( sfb_read_buf( (addr + data_len), ( uint8_t* )&infor->infor_crc, sizeof(uint32_t) ) == pdFAIL )
    {
		return 0;
	}    
	data_len += sizeof(uint32_t);
	data_crc = calculate_crc32(CRC_INIT, (uint8_t *)infor->infor_p , infor->infor_len );	
	if( infor->infor_crc != data_crc )
	{
		return 0;
	}
	return data_len;
}


